package com.ruoyi.user.controller;

import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.user.domain.UserOrder;
import com.ruoyi.user.service.IUserOrderService;
import com.ruoyi.user.service.thirdpay.alipay.AlipayService;
import com.ruoyi.user.service.thirdpay.wx.WxPayService;
import com.ruoyi.user.utils.BigDecimalUtil;
import com.ruoyi.user.utils.GetRequestIp;
import com.ruoyi.user.utils.PayChannel;
import com.ruoyi.user.utils.StringUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;

/**
 * 统一支付控制器
 * 处理各种支付渠道的支付请求，包括支付宝、微信等
 *
 * @author houyong
 */
@RestController
@RequestMapping(value = "/pay")
@RefreshScope
public class PayController {

    @Autowired
    private IUserOrderService userOrderService;

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private WxPayService wxPayService;

    /**
     * 处理支付宝和微信的扫码支付请求。
     * 通过订单号和支付渠道参数，生成相应的支付扫码凭证。
     * 支付宝和微信支付的处理逻辑有所不同，根据渠道参数进行分支处理。
     *
     * @param orderId 订单号，用于查询订单信息。
     * @param channel 支付渠道，区分支付宝和微信支付。
     * @param request HTTP请求对象，用于获取请求IP地址（微信支付需要）。
     * @return 根据支付渠道生成的支付凭证，或者错误信息。
     */
    @Operation(summary = "处理支付宝和微信的扫码支付请求")
    @PostMapping(value = "/scan/qrcode/pay/charge")
    public AjaxResult scanQrCodePayCharge(@RequestParam String orderId, @RequestParam String channel,
                                          HttpServletRequest request) {
        try {
            // 根据订单号查询订单信息
            UserOrder order = userOrderService.findOrderByOrderId(orderId);
            // 检查订单是否存在和支付状态
            if (order == null) {
                return AjaxResult.error("订单信息不存在,请刷新后重试");
            }
            // 检查订单是否已支付
            if (order.getPayTime() != null) {
                return AjaxResult.error("订单已经支付,请勿重复支付");
            }
            // 根据支付渠道生成支付凭证
            if (PayChannel.ChannelType.ALIPAY.getValue().equals(channel)) {
                // 计算支付宝支付金额，单位为分
                String totalFee = "0";
                if (order.getNeedPayTotalFee() != null) {
                    totalFee = String.valueOf(order.getNeedPayTotalFee());
                } else {
                    totalFee = String.valueOf(BigDecimalUtil.div(BigDecimal.valueOf(order.getFee()), new BigDecimal("100"), 2));
                }
                // 生成支付宝扫码支付订单
                return alipayService.getAlipayOrderChargeForScanQrCode(orderId, totalFee,
                        StringUtils.replaceAllChinesePunctuation(order.getGoodsSubject()),
                        StringUtils.replaceAllChinesePunctuation(order.getBody()));
            } else if (PayChannel.ChannelType.WX.getValue().equals(channel)) {
                // 生成微信扫码支付订单
                String wxOrderChargeForScanQrCode = wxPayService.generateChargeForScanQrCode(order, GetRequestIp.getIpAddress(request));
                if (wxOrderChargeForScanQrCode != null) {
                    return AjaxResult.success(wxOrderChargeForScanQrCode);
                } else {
                    return AjaxResult.error("生成微信支付二维码失败");
                }
            }
            return AjaxResult.error("不支持的支付渠道");
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("支付处理异常: " + e.getMessage());
        }
    }

    @Operation(summary = "支付宝退款查询")
    @Parameters({
            @Parameter(name = "orderId", description = "商户订单号", required = true),
            @Parameter(name = "refundId", description = "退款订单号", required = true)
    })
    @GetMapping(value = "/alipay/refund/query")
    public AjaxResult alipayRefundQuery(@RequestParam String orderId, @RequestParam String refundId) {
        try {
            /**
             * refundId 取表refund_info 表中的refund_id字段
             */
            AlipayTradeFastpayRefundQueryResponse refundResponse = alipayService.searchAliPayRefundResult(orderId, refundId);
            if (refundResponse.isSuccess()) {
                return AjaxResult.success(refundResponse);
            } else {
                return AjaxResult.error("调用失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

    @Operation(summary = "支付宝交易订单查询")
    @Parameters({
            @Parameter(name = "orderId", description = "商户订单号", required = false),
            @Parameter(name = "tradeNo", description = "支付宝交易流水号", required = false)
    })
    @GetMapping(value = "/alipay/order/query")
    public AjaxResult alipayTradeQuery(@RequestParam(required = false) String orderId,
                                       @RequestParam(required = false) String tradeNo) {
        try {
            AlipayTradeQueryResponse alipayTradeQueryResponse = alipayService.alipayTradeQuery(orderId, tradeNo);
            if (alipayTradeQueryResponse.isSuccess()) {
                return AjaxResult.success(alipayTradeQueryResponse);
            } else {
                return AjaxResult.error("调用失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }
}